package com.sxj.PDMS.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sxj.PDMS.common.ErrorCode;
import com.sxj.PDMS.context.BaseContext;
import com.sxj.PDMS.exception.BusinessException;
import com.sxj.PDMS.mapper.*;
import com.sxj.PDMS.model.dto.student.StudentRegisterRequest;
import com.sxj.PDMS.model.entity.*;
import com.sxj.PDMS.model.vo.StudentLoginVO;
import com.sxj.PDMS.model.vo.StudentTimesVO;
import com.sxj.PDMS.service.StudentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpServletRequest;

import static com.sxj.PDMS.utils.VerifyUtil.*;

/**
 * @author sunxi
 * @description 针对表【student(学生信息列表)】的数据库操作Service实现
 * @createDate 2024-06-06 17:29:35
 */
@Service
@Slf4j
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student>
        implements StudentService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private ActivistApplicationInformationListMapper activistApplicationInformationListMapper;
    @Autowired
    private DevelopTheObjectApplicationInformationListMapper developTheObjectApplicationInformationListMapper;
    @Autowired
    private ListOfProbationaryPartyApplicationInformationMapper listOfProbationaryPartyApplicationInformationMapper;
    @Autowired
    private FullPartyMemberInformationListMapper fullPartyMemberInformationListMapper;


    public static final String SALT = "tyutrjxy";

    /**
     * 用户注册
     *
     * @param studentRegisterRequest 学生
     * @return 学生名字
     */

    public String studentRegister(StudentRegisterRequest studentRegisterRequest) {
        // 1. 校验
        if (StringUtils.isAnyBlank(studentRegisterRequest.getName(),
                studentRegisterRequest.getStudentNumber(), studentRegisterRequest.getIdNumber(),
                studentRegisterRequest.getGrade(), studentRegisterRequest.getGender(),
                studentRegisterRequest.getFullHomeAddress(), studentRegisterRequest.getLiveInTheDormitory(),
                studentRegisterRequest.getNation(), studentRegisterRequest.getNativePlace(),
                studentRegisterRequest.getPhoneNumber(), studentRegisterRequest.getThePartyBranch(),
                studentRegisterRequest.getPassword(), studentRegisterRequest.getCheckPassword()) && studentRegisterRequest.getDateOfBirth() == null
                && studentRegisterRequest.getTheDateOfSubmissionOfTheApplicationForPartyMembership() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }
        if (studentRegisterRequest.getStudentNumber().length() < 6) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号过短");
        }
        if (studentRegisterRequest.getStudentNumber().length() > 18) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号过长");
        }
        if (studentRegisterRequest.getPassword().length() < 6 || studentRegisterRequest.getCheckPassword().length() < 6) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码过短");
        }
        // 密码和校验密码相同
        if (!studentRegisterRequest.getPassword().equals(studentRegisterRequest.getCheckPassword())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致");
        }
        if (!isValidChinesePhoneNumber(studentRegisterRequest.getPhoneNumber())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "电话格式错误");
        }
        if (!isValidChineseID(studentRegisterRequest.getIdNumber())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "身份证号格式错误");
        }
        if (!isValidEmail(studentRegisterRequest.getEmail())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "邮箱格式错误");
        }


        synchronized (studentRegisterRequest.getStudentNumber().intern()) {
            // 账户不能重复
            QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("student_number", studentRegisterRequest.getStudentNumber());
            long count = this.baseMapper.selectCount(queryWrapper);
            if (count > 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号重复");
            }
            // 2. 加密
            String encryptPassword = DigestUtils.md5DigestAsHex((SALT + studentRegisterRequest.getPassword()).getBytes());
            // 3. 插入数据
            Student student = new Student();

            BeanUtils.copyProperties(studentRegisterRequest, student);
            student.setPassword(encryptPassword);

            boolean saveResult = this.save(student);
            if (!saveResult) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败，数据库错误");
            }
            return student.getName();
        }
    }

    /**
     * 用户登录
     *
     * @param studentNumber 学号
     * @param password      密码
     * @param request
     * @return
     */
    @Override
    public StudentLoginVO login(String studentNumber, String password, HttpServletRequest request) {
        // 1. 校验
        if (StringUtils.isAnyBlank(studentNumber, password)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }
        if (studentNumber.length() < 4) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号错误");
        }
        if (password.length() < 6) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码错误");
        }
        // 2. 加密
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + password).getBytes());
        System.out.println("加密后的密码：" + encryptPassword);
        // todo 走redis缓存
        Object object = redisTemplate.opsForValue().get("student:student_" + studentNumber);
        if (object != null) {
            Student student = (Student) object;
            if (!student.getPassword().equals(encryptPassword)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或密码错误");
            }
            StudentLoginVO studentLoginVO = new StudentLoginVO();
            BeanUtils.copyProperties(student, studentLoginVO);
            return studentLoginVO;
        } else {
            //缓存中没有，从数据库中查询
            // 查询用户是否存在
            QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("student_number", studentNumber);
            queryWrapper.eq("password", encryptPassword);
            Student student = this.baseMapper.selectOne(queryWrapper);
            // 用户不存在
            if (student == null) {
                log.info("user login failed, userAccount cannot match userPassword");
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或密码错误");
            } else {
                // 用户存在，存入缓存
                redisTemplate.opsForValue().set("student:student_" + studentNumber, student, 7, TimeUnit.DAYS);
                StudentLoginVO studentLoginVO = new StudentLoginVO();
                BeanUtils.copyProperties(student, studentLoginVO);
                return studentLoginVO;
            }

            // 3. 记录用户的登录态
//        request.getSession().setAttribute(USER_LOGIN_STATE, user);
//        return this.getLoginUserVO(user);


        }
    }

    @Override
    public StudentLoginVO getLoginStudent() {
        // 先判断是否已登录
        String currentId = BaseContext.getCurrentId();
        if (StringUtils.isBlank(currentId)) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        // todo 走redis缓存
        Object object = redisTemplate.opsForValue().get("student:student_" + currentId);
        if (object != null) {
            Student student = (Student) object;
            StudentLoginVO studentLoginVO = new StudentLoginVO();
            BeanUtils.copyProperties(student, studentLoginVO);
            return studentLoginVO;
        } else {
            //缓存中没有，从数据库中查询
            // 从数据库查询（追求性能的话可以注释，直接走缓存）
            Student student = this.baseMapper.selectById(currentId);
            if (student == null) {
                throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
            } else {
                redisTemplate.opsForValue().set("student:student_" + currentId, student, 7, TimeUnit.DAYS);
                StudentLoginVO studentLoginVO = new StudentLoginVO();
                BeanUtils.copyProperties(student, studentLoginVO);
                return studentLoginVO;
            }
        }
    }

    @Override
    public StudentTimesVO selectStudentTimes(String studentNumber) {
        // 1. 查询学生信息
        QueryWrapper<Student> queryWrapperStudent = new QueryWrapper<>();
        queryWrapperStudent.eq("student_number", studentNumber);
        Student student = studentMapper.selectOne(queryWrapperStudent);
        if (student == null) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "没有该学生");
        }
        StudentTimesVO studentTimesVO = new StudentTimesVO();
        //2.看学生发展状态 0群众 1团员 2已提交入党申请书 3积极分子 4发展对象 5预备党员 6正式党员
        if (student.getStatue() == null) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "学生状态为空");
        }
        if (student.getStatue().equals(2)) {
            studentTimesVO.setDate_of_application_for_Party_membership(formatDate(student.getTheDateOfSubmissionOfTheApplicationForPartyMembership()));
        }
        if (student.getStatue().equals(3)) {
            QueryWrapper<ActivistApplicationInformationList> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("student_number", studentNumber);
            ActivistApplicationInformationList activistApplicationInformationList = activistApplicationInformationListMapper.selectOne(queryWrapper);
            if (activistApplicationInformationList != null) {
                studentTimesVO.setDate_of_application_for_Party_membership(formatDate(activistApplicationInformationList.getDateOfApplicationForPartyMembership()));
                studentTimesVO.setDetermine_activist_time(formatDate(activistApplicationInformationList.getBranchTime()));
            }
        } else if (student.getStatue().equals(4)) {
            QueryWrapper<DevelopTheObjectApplicationInformationList> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("student_number", studentNumber);
            DevelopTheObjectApplicationInformationList developTheObjectApplicationInformationList = developTheObjectApplicationInformationListMapper.selectOne(queryWrapper);
            if (developTheObjectApplicationInformationList != null) {
                studentTimesVO.setDate_of_application_for_Party_membership(formatDate(developTheObjectApplicationInformationList.getDateOfApplicationForPartyMembership()));
                studentTimesVO.setDetermine_activist_time(formatDate(developTheObjectApplicationInformationList.getDetermineActivistTime()));
                studentTimesVO.setDetermine_the_development_object_time(formatDate(developTheObjectApplicationInformationList.getBranchTime()));
            }
        } else if (student.getStatue().equals(5)) {
            QueryWrapper<ListOfProbationaryPartyApplicationInformation> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("student_number", studentNumber);
            ListOfProbationaryPartyApplicationInformation listOfProbationaryPartyApplicationInformation = listOfProbationaryPartyApplicationInformationMapper.selectOne(queryWrapper);
            if (listOfProbationaryPartyApplicationInformation != null) {
                studentTimesVO.setDate_of_application_for_Party_membership(formatDate(listOfProbationaryPartyApplicationInformation.getDateOfApplicationForPartyMembership()));
                studentTimesVO.setDetermine_activist_time(formatDate(listOfProbationaryPartyApplicationInformation.getDetermineActivistTime()));
                studentTimesVO.setDetermine_the_development_object_time(formatDate(listOfProbationaryPartyApplicationInformation.getDetermineTheDevelopmentObjectTime()));
                studentTimesVO.setDetermine_probationary_membership_time(formatDate(listOfProbationaryPartyApplicationInformation.getBranchTime()));
            }
        } else if (student.getStatue().equals(6)) {
            QueryWrapper<FullPartyMemberInformationList> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("student_number", studentNumber);
            FullPartyMemberInformationList fullPartyMemberInformationList = fullPartyMemberInformationListMapper.selectOne(queryWrapper);
            if (fullPartyMemberInformationList != null) {
                studentTimesVO.setDate_of_application_for_Party_membership(formatDate(fullPartyMemberInformationList.getDateOfApplicationForPartyMembership()));
                studentTimesVO.setDetermine_activist_time(formatDate(fullPartyMemberInformationList.getDetermineActivistTime()));
                studentTimesVO.setDetermine_the_development_object_time(formatDate(fullPartyMemberInformationList.getDetermineTheDevelopmentObjectTime()));
                studentTimesVO.setDetermine_probationary_membership_time(formatDate(fullPartyMemberInformationList.getDetermineProbationaryMembershipTime()));
                studentTimesVO.setDetermine_formal_membership_time(formatDate(fullPartyMemberInformationList.getBranchTime()));
            }
        }
        return studentTimesVO;
    }
}




